package com.db.transport.exchange;

import com.db.transport.exchange.listener.SessionExchangeListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Logger;

/**
 * @author nulls.narik
 */
public class SessionExchange implements Runnable {

    private static Logger logger = Logger.getLogger(SessionExchange.class.getName());

    private final String exchangeID;
    private final Socket socket;
    protected final BufferedReader reader;
    protected final PrintWriter writer;
    private volatile boolean isShutdown;

    public String getExchangeID() {
        return exchangeID;
    }

    public SessionExchange(String exchangeID, Socket socket) throws IOException {
        this(exchangeID, socket,
                new BufferedReader( new InputStreamReader(socket.getInputStream())),
                                    new PrintWriter(socket.getOutputStream(), true));
    }

    public SessionExchange(String exchangeID, Socket socket, BufferedReader reader, PrintWriter writer) {
        this.exchangeID = exchangeID;
        this.socket = socket;
        this.reader = reader;
        this.writer = writer;
        this.listeners = new CopyOnWriteArraySet<SessionExchangeListener>();
        this.isShutdown = false;
    }

    @Override
    public void run() {
        // TODO: нормальную остановку
        while (!isShutdown && !Thread.currentThread().isInterrupted()) {
            String message = null;
            try {
                synchronized (reader) {
                    message = reader.readLine();
                    newMessage(message);
                }
            } catch (IOException e) {
                logger.warning(String.format("Exchange [%s]: error when try get new message", exchangeID));
            }
        }
    }

    public void shutdown() {
        isShutdown = true;
    }

    private final Set<SessionExchangeListener> listeners;

    public void addListener(SessionExchangeListener listener) {
        listeners.add(listener);
    }

    private void newMessage(String message) {
        Iterator<SessionExchangeListener> iterator = listeners.iterator();
        while (iterator.hasNext()) {
            iterator.next().newMessage(message);
        }
    }

    public void sendMessage(String message) {
        logger.info(String.format("Exchange [%s] send new message: \"%s\"", exchangeID, message));
        synchronized (writer) {
            writer.println(message);
        }
    }
}
